package gui;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Scanner;

import javax.swing.*;
import javax.swing.event.*;

@SuppressWarnings("serial")
public class UndoableTextArea extends JTextArea implements CaretListener {
	private LinkedList<String> undoStack, redoStack;
	private String prevText;
	private boolean userUpdating, needsSaving;
	
	public UndoableTextArea() {
		super();
		undoStack = new LinkedList<String>();
		resetRedo();
		prevText = "";
		addCaretListener(this);
		userUpdating = true;
		needsSaving = false;
	}
	
	public boolean needsSaving() {
		return needsSaving;
	}
	
	public void save(File f) throws IOException {
		PrintWriter p = new PrintWriter(new FileWriter(f));
		p.println(getText());
		p.close();
		needsSaving = false;
	}
	
	public void open(File f) throws FileNotFoundException {
		Scanner s = new Scanner(f);
		String textRead = "";
		while (s.hasNextLine()) {
			textRead += s.nextLine() + "\n";
		}
		changeText(textRead);
		needsSaving = false;
		/*
		setText("");
		while (s.hasNextLine()) {
			setText(getText() + s.nextLine() + "\n");
		}
		resetUndo();
		needsSaving = false;
		*/
	}
	
	private void resetUndo() {
		undoStack = new LinkedList<String>();
		resetRedo();
	}
	
	private void resetRedo() {
		redoStack = new LinkedList<String>();
	}

	public void undo() {
		if (!undoStack.isEmpty()) {
			redoStack.addFirst(getText());
			changeText(undoStack.removeFirst());
		}
	}

	public void redo() {
		if (!redoStack.isEmpty()) {
			undoStack.addFirst(getText());
			changeText(redoStack.removeFirst());
		}
	}
	
	private void changeText(String newText) {
		userUpdating = false;
		setText(newText);
		userUpdating = true;
		needsSaving = true;
	}

	public void caretUpdate(CaretEvent e) {
		if (userUpdating && !prevText.equals(getText())) {
			undoStack.addFirst(prevText);
			resetRedo();
			needsSaving = true;
		} 
		prevText = getText();
	}
}
